package dp;

import java.util.Arrays;
import java.util.Scanner;

//树形dp
public class TreeDp {

	private static int[][] dp;
	
	public static void main_2(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n;
		int[] father;
		int root;
		while(scanner.hasNext()){
			n = scanner.nextInt();
			dp = new int[n][2];
			father = new int[n];
			Arrays.fill(father, -1);
			root = 0;
			for (int i = 0; i < n; i++) {
				dp[i][1] = scanner.nextInt();
			}
			int childNo = scanner.nextInt();
			int fatherNo = scanner.nextInt();
			while(childNo != 0 || fatherNo != 0){
				childNo--;
				fatherNo--;
				father[childNo] = fatherNo;
				//记录根节点的编号
				if(root == childNo){
					root = fatherNo;
				}
				childNo = scanner.nextInt();
				fatherNo = scanner.nextInt();
			}
			// System.out.println(" root:" + root);
			//查找根结点  
			while(father[root] != -1 && father[root] != 0){
				root = father[root];
			}
			treeDp(root, father);
			System.out.println(Math.max(dp[root][0], dp[root][1]));
		}
		scanner.close();
	}
	
	//首先从最简单的参加party开始    POJ 2342
	//每个人都直接上司，不能一起参加活动，求最大的活跃因子
	//这道题其实跟house robber III是一样的，只不过是多叉树
	//但是是一道简单的树形dp问题
	
	//father表示是i号人对应的上司编号
	public static void treeDp(int root, int[] father){
		//dp[i][0]和dp[i][1]表示第i号来或者不来
		// dp[i][0] += max(dp[j][1], dp[j][0]) , j为i的下属标号
		// dp[i][1] += dp[j][0], j为i的下属标号
		// visited[root] = true;
		// System.out.println("root: " + root);
		for(int i = 0; i < father.length; i++){
			if(father[i] == root){
				//从最底端的结点开始，开始递归
				treeDp(i, father);
				dp[root][0] += Math.max(dp[i][0], dp[i][1]);
				dp[root][1] += dp[i][0];
			}
		}
	}
	
	
	//runTime error, don't know why
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n;
		int[][] dp;
		int[] father;
		while(scanner.hasNext()){
			n = scanner.nextInt();
			dp = new int[n][2];
			father = new int[n];
			Arrays.fill(father, -1);
			int root = -1;
			scanner.nextLine();
			for(int i = 0 ; i < n; i++){
				String road = scanner.nextLine();
				String[] roads = road.split(" ");
				// System.out.println("lenght: " + roads.length);
				for(int j = 1; j < roads.length; j++){
					int index = Integer.parseInt(roads[j]);
					int cur = Integer.parseInt(road.substring(0, road.indexOf(':')));
					father[index] = cur;
					if(root == -1){
						root = cur;
						// System.out.println("root change :" + root);
					}
				}
			}
//			for(int i = 0; i < father.length; i++){
//				System.out.print(father[i] + "  ");
//			}
//			System.out.println();
			if(root != -1){
				tree(root, father, dp);
				System.out.println(Math.min(dp[root][0], dp[root][1]));
			}else{
				System.out.println(0);
			}
//			for(int i = 0; i < dp.length; i++){
//				System.out.print(dp[i][0] + "  " + dp[i][1]);
//				System.out.println();
//			}
		}
		scanner.close();
	}
	
	//POJ 1463 Strategic game
	//对于树形的城市，设立最少的哨兵，使哨兵能够观察到每条边
	//同样的，我们设dp[i][0] 为该条边不设哨兵, dp[i][1]为该条边设哨兵
	//如果该条边不设，那么所有的子节点都要设
	// dp[i][0] = sum(dp[j][1]) (j为i的子节点)
	// dp[i][1] = sum{min(dp[j][1], dp[j][0])} + 1 + 1 (j为i的子节点)
	public static void tree(int root, int[] father, int[][] dp){
		for(int i = 0; i < father.length; i++){
			if(father[i] == root){
				//从最底端的结点开始，开始递归
				tree(i, father, dp);
				dp[root][0] += dp[i][1];
				dp[root][1] += Math.min(dp[i][1], dp[i][0]);
			}
		}
		dp[root][1] += 1;
	}
}
